<?php

/**
 * 支付回调接口
 */
class PaymentController extends ControllerBase {

    /**
     * 微信支付回调地址
     * 接口请求地址： [域名] + /payment/wepay_notify/
     */
    public function wepay_notifyAction() {
        // postStr
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
        $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        if ($postObj) {
            // orderid
            $serial_number = $postObj->out_trade_no;
            // 微信交易单号
            $transaction_id = $postObj->transaction_id;
            // 更新订单状态
            $orderInfo = Orders::findFirst("serial_number = '$serial_number'");
            if ($orderInfo && $orderInfo->status != 'payed') {
                $orderInfo->wepay_serial = $transaction_id;
                $orderInfo->status = 'payed';
                try {
                    $orderInfo->save();
                    // 减库存
                    Order::cutProductStock($orderInfo->order_id);
                    // 积分结算
                    Order::updateUserCredit($orderInfo->order_id, $orderInfo->client_id);
                    // 返回success
                    echo "<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>";
                } catch (Exception $ex) {
                    Util::log('wepay_notify_error:' . PHP_EOL . $postStr . PHP_EOL . $ex->getMessage());
                }
            }
        } else {
            throw new Exception('ERROR');
        }
    }

    /**
     * 支付宝回调地址
     * 接口请求地址： [域名] + /payment/alipay_notify/
     */
    public function alipay_notifyAction() {

        if ($_POST['seller_email'] != 'yj@yunjie-e.cn') {
            return false;
        }

        // 内部订单号
        $serial_number = $_POST['out_trade_no'];
        //支付宝交易号
        $transaction_id = $_POST['trade_no'];
        //交易状态
        $trade_status = $_POST['trade_status'];

        # Util::log('alipay_notify_error:' . PHP_EOL . json_encode($_POST));

        if ($trade_status == 'TRADE_FINISHED') {
            //注意：
            //退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
            //判断该笔订单是否在商户网站中已经做过处理
            //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
            //如果有做过处理，不执行商户的业务程序
            //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
            echo "success";
        } else if ($trade_status == 'TRADE_SUCCESS') {
            // 付款完成后，支付宝系统发送该交易状态通知
            // 更新订单状态
            $orderInfo = Order::findFirst("serial_number = '$serial_number'");
            if ($orderInfo && $orderInfo->status != 'payed') {
                $orderInfo->wepay_serial = $transaction_id;
                $orderInfo->status = 'payed';
                try {
                    $orderInfo->save();
                    // 减库存
                    Order::cutProductStock($orderInfo->order_id);
                    // 积分结算
                    Order::updateUserCredit($orderInfo->order_id, $orderInfo->client_id);
                    // 返回success
                    echo "success";
                } catch (Exception $ex) {
                    Util::log('alipay_notify_error[SYSTEM]:' . PHP_EOL . json_encode($_POST));
                }
            } else {
                Util::log('alipay_notify_error[SYSTEM]:' . PHP_EOL . json_encode($_POST));
            }
            //判断该笔订单是否在商户网站中已经做过处理
            //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
            //如果有做过处理，不执行商户的业务程序
            //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
        }

    }

    /**
     * 支付宝退款回调地址
     */
    public function alipay_refund_notifyAction() {
        // 通知类型
        $notify_type = $_POST['notify_type'];
        // 校验
        if ($notify_type == 'batch_refund_notify') {
            //批量退款数据中转账成功的笔数
            $success_num = $_POST['success_num'];
            // 退款批次
            $batch_no = $_POST['batch_no'];
            // 检查是否已处理退款单
            $refundmentCheck = OrderRefundMent::findFirst("refund_serial = '$batch_no'");
            // 退款单已处理
            if ($refundmentCheck) {
                Util::log('alipay_refund_notify_error_batch_no_refunded:' . PHP_EOL . json_encode($_POST));
                return false;
            }
            if (is_numeric($success_num) && $success_num > 0 && !empty($batch_no)) {
                //批量退款数据中的详细信息
                $result_details = $_POST['result_details'];
                // 2010031906272929 ^ 80 ^ SUCCESS $ jax_chuanhang@alipay.com ^ 2088101003147483 ^ 0.01 ^ SUCCESS
                $data = explode('^', $result_details);
                // 支付宝交易单号
                $serial_number = trim($data[0]);
                // 退款金额
                $refund_fee = floatval($data[1]);
                // 退款状态
                $refund_status = $data[2];
                // 校验是否成功
                if (preg_match("/SUCCESS/i", $refund_status) && $refund_fee > 0 && !empty($serial_number)) {
                    $order = Order::findFirst("wepay_serial = '$serial_number'");
                    if ($order) {
                        try {
                            // 修改订单数据
                            if ($order->order_amount == ($order->order_refund_amount + $refund_fee)) {
                                // 修改订单状态
                                $order->status = 'refunded';
                                // 加库存
                                Order::cutProductStock($order->order_id, false);
                            }
                            // 记录订单已退款金额
                            $order->order_refund_amount = $order->order_refund_amount + $refund_fee;
                            // 对应的用户
                            $user = User::findFirst("client_id = $order->client_id");
                            // 保存订单数据
                            $order->save();
                            if ($user) {
                                // 回扣订单赠送的积分
                                if ($order->order_credit_add > 0) {
                                    try {
                                        $creditCut = ceil($order->order_credit_add * ($refund_fee / $order->order_amount));
                                        $user->client_credit -= $creditCut;
                                        if ($user->save()) {
                                            CreditRecord::log($user->client_id, -1 * $creditCut, 0, $order->order_id, '退款减去赠送的积分-' . $creditCut);
                                        }
                                    } catch (Exception $ex) {
                                        // 订单积分回扣错误
                                        Util::log('alipay_refund_notify_error_credit_cut:' . PHP_EOL . json_encode($_POST) . PHP_EOL . $ex->getMessage());
                                    }
                                }
                                // 回扣订单使用的积分
                                if ($order->order_credit > 0) {
                                    try {
                                        $creditAdd = ceil($order->order_credit * ($refund_fee / $order->order_amount));
                                        $user->client_credit += $creditAdd;
                                        if ($user->save()) {
                                            CreditRecord::log($user->client_id, $creditAdd, 0, $order->order_id, '退款返回积分+' . $creditAdd);
                                        }
                                    } catch (Exception $ex) {
                                        // 积分回扣错误
                                        Util::log('alipay_refund_notify_error_credit:' . PHP_EOL . json_encode($_POST) . PHP_EOL . $ex->getMessage());
                                    }
                                }
                            }
                            // 写入退款记录
                            $refundRecord = new OrderRefundMent();
                            $refundRecord->order_id = $order->order_id;
                            $refundRecord->refund_amount = $refund_fee;
                            $refundRecord->serial_number = $serial_number;
                            $refundRecord->refund_serial = $batch_no;
                            $refundRecord->refund_time = date('Y-m-d H:i:s');
                            $refundRecord->payment_type = $order->wepay_method;
                            $refundRecord->save();
                            // 返回success
                            echo "success";
                        } catch (Exception $ex) {
                            // system error
                            Util::log('alipay_refund_notify_error_1:' . PHP_EOL . json_encode($_POST) . PHP_EOL . $ex->getMessage());
                        }
                    } else {
                        // order not found
                        Util::log('alipay_refund_notify_error_2:' . PHP_EOL . json_encode($_POST) . PHP_EOL . 'order not found');
                    }
                } else {
                    Util::log('alipay_refund_notify_error_3:' . PHP_EOL . json_encode($_POST));
                    // refund errors
                }
                // 退款结果明细：
                // 退手续费结果返回格式   交易号^退款金额^处理结果\$退费账号^退费账户ID^退费金额^处理结果；
                // 不退手续费结果返回格式 交易号^退款金额^处理结果。
                // 若退款申请提交成功，处理结果会返回“SUCCESS”。若提交失败，退款的处理结果中会有报错码
            } else {
                echo 'failed';
            }
        }
    }

    /**
     * 获取微信支付签名数据包 [POST]
     * @param int $order_id 订单编号
     * @param int $device_type 设备类型 0:IOS, 1:Android
     * 接口请求地址： /payment/getBizSignPackage/
     * @example (IOS)返回数据JSON：{"appId":"wxa22a618ec92993e3","partnerId":"1239952602","prepayId":"asdasdasdasdasdasd","timeStamp":"1448458639","nonceStr":"g85vA2S5xipx6IFq","package":"Sign=WXPay","sign":"DE48328E7AF0B32FA81783812D0FFD15"}
     * @example (ANDROID)返回数据JSON：{"appId":"wxa22a618ec92993e3","partnerId":"1239952602","prepayId":"asdasdasdasdasdasd","timeStamp":"1448458956","nonceStr":"wg086WAde104kewP","appId":"wxa22a618ec92993e3","packageValue":"Sign=WXPay","sign":"0E3EB92916D5AC36FD939D4ACC10D42E"}
     */
    public function getBizSignPackageWxAction() {
        $orderId = $this->request->getPost('order_id');
        $deviceType = InputUtil::digitDefault($this->request->getPost('device_type'), 0);
        if ($orderId > 0) {
            $package = Payment::createWxpayPackage($orderId, $deviceType);
            $this->echoJson($package);
        } else {
            $this->echoErrcode(ErrorCode::$ERR_PARAMS_ERROR);
        }
    }

    /**
     * 获取支付宝快捷支付签名数据包 [POST]
     * @param int $order_id 订单编号
     * 接口请求地址： /payment/getBizSignPackageAlipay/
     * @example <b>请转义\"</b>
     * @example 返回数据STRING："_input_charset=\"utf-8\"&body=\"asdasdasd\"&notify_url=\"http%3A%2F%2F182.92.164.200%3A82%2Fpayment%2Falipay_notify%2F\"&out_trade_no=\"2015112510425214\"&partner=\"2088021692256940\"&payment_type=\"1\"&seller_id=\"2088021692256940\"&service=\"mobile.securitypay.pay\"&subject=\"asdasdasd\"&total_fee=\"30\"&sign=\"0c4c226dc2b3cf4f4a6925dca387b748\"&sign_type=\"MD5\""
     */
    public function getBizSignPackageAlipayAction() {
        $orderId = $this->request->getPost('order_id');
        if ($orderId > 0) {
            $package = Payment::createAlipayPackage($orderId);
            $this->echoJson($package);
        } else {
            $this->echoErrcode(ErrorCode::$ERR_PARAMS_ERROR);
        }
    }

}
